<!doctype html>
<html lang="en">
 <head> 
  <meta charset="UTF-8"> 
  <meta name="description" content="燎火的个人博客"> 
  <meta name="keyword" content="燎火,qq799378666,软件开发,java,c#,js,html,html5,css"> 
  <title>工作中常用到的Java反射</title> 
  <script src="/js/jquery-1.11.1.min.js"></script> 
  <script src="/js/bootstrap-3.3.5/js/bootstrap.js"></script> 
  <link href="/js/bootstrap-3.3.5/css/bootstrap.css" rel="stylesheet"> 
  <script src="/js/base.js"></script> 
  <script src="/js/nav.js"></script> 
  <script src="/js/jquery.toTop.min.js"></script> 
  <link href="/style/article.css" rel="stylesheet"> 
 </head> 
 <body> 
  <div id="main"> 
   <h3 id="title">工作中常用到的Java反射</h3> 
   <div id="content">
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px;">这次提到的Java反射涉及的代码比较多。因为工作中经常用到反射，对代码做了很多抽象以及过滤器。虽然代码量很多，但是简单易用，过滤插件也易修改。</p>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px;">下面介绍下工作中哪些地方比较容易用到反射。比如插件或者过滤器，如果抽象的子类比较少，配置成XML等结构也是可以达到同样的效果。如果希望灵活一些，添加了插件或者过滤器代码子类后希望可以直接使用。可能反射会比较好点，通过扫描所有class或者jar文件，得到所有继承的子类。如果每次调用都扫描所有的文件会比较影响性能。所以在实现里面加入反射缓存，对所要获取反射子类时涉及的所有参数作为一个key缓存所有的反射结果。下次如果是同样的key，就不在重新扫描。</p>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px;">代码示例如下：</p>
    <pre class="hljs gradle" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{		//设置扫描范围，可以是class文件所在位置例如bin下或者是mysql开头或者mysql结尾的jar,
		//设置为""为全部都扫描,这种比较耗时
		ReflectUtils.createSharedReflections("classes",&nbsp;"bin",&nbsp;"mysql");		try&nbsp;{			//调试阶段可以设置每次都全扫描
			//Beans.setDesignTime(true);
			final&nbsp;Collection&lt;String&gt;&nbsp;subTypes&nbsp;=&nbsp;ReflectUtils.listSubClass(IA.class);//
			for&nbsp;(final&nbsp;String&nbsp;subType&nbsp;:&nbsp;subTypes)&nbsp;{				//这里获取的是所有继承IA的子类
				System.out.println(subType);				final&nbsp;IA&nbsp;impl&nbsp;=&nbsp;ReflectUtils.initClass(subType,&nbsp;IA.class);				if&nbsp;(null&nbsp;==&nbsp;impl)					continue;				//通过该方式，可以统一做操作，
				impl.print();
			}
		}&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;{
			e.printStackTrace();
		}
	}</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px;">代码执行结果：</p>
    <pre class="hljs swift" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">//缓存文件，避免每次调用反射都重新扫描//如果删除该文件，再次调用反射时，会重新扫描，一般会在代码里面有添加子类的时候会删除该文件XmlUtils.readXml&nbsp;failure:.\configuration.REF&nbsp;(系统找不到指定的文件。)
net.simple.reflect.test.Bnet.simple.reflect.test.Bnet.simple.reflect.test.Dnet.simple.reflect.test.V</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px;">具体的类里面如何实现的大家就看下源码吧，这里贴出两个核心类的代码。源码地址：<a href="https://git.oschina.net/eliyanfei/api_tools" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border: none; outline: 0px; transition: color 0.3s; text-decoration: none; color: rgb(68, 102, 187);">https://git.oschina.net/eliyanfei/api_tools</a></p>
    <pre class="hljs gradle" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">package&nbsp;net.simple.reflect;import&nbsp;java.io.File;import&nbsp;java.io.IOException;import&nbsp;java.net.JarURLConnection;import&nbsp;java.net.URL;import&nbsp;java.net.URLDecoder;import&nbsp;java.util.ArrayList;import&nbsp;java.util.Collection;import&nbsp;java.util.Enumeration;import&nbsp;java.util.LinkedHashMap;import&nbsp;java.util.List;import&nbsp;java.util.Map;import&nbsp;java.util.concurrent.TimeUnit;import&nbsp;java.util.jar.JarEntry;import&nbsp;java.util.jar.JarFile;import&nbsp;java.util.zip.ZipEntry;import&nbsp;net.simple.reflect.filter.IPathURLFilter;import&nbsp;net.simple.reflect.filter.ISubTypeFilter;import&nbsp;net.simple.reflect.filter.ITypeFilter;import&nbsp;org.w3c.dom.Document;import&nbsp;org.w3c.dom.Element;/**
&nbsp;*&nbsp;
&nbsp;*&nbsp;@author&nbsp;李岩飞
&nbsp;*&nbsp;@email&nbsp;eliyanfei@126.com	
&nbsp;*&nbsp;2016年11月2日&nbsp;下午3:23:49
&nbsp;*
&nbsp;*/public&nbsp;final&nbsp;class&nbsp;Reflections&nbsp;{	private&nbsp;final&nbsp;Collection&lt;URL&gt;&nbsp;pathUrls;	private&nbsp;final&nbsp;Collection&lt;IPathURLFilter&gt;&nbsp;pathURLfilters;	private&nbsp;final&nbsp;Collection&lt;ITypeFilter&gt;&nbsp;typeFilters;	private&nbsp;ISubTypeFilter&nbsp;subTypeFilter;	public&nbsp;Reflections()&nbsp;{
		typeFilters&nbsp;=&nbsp;new&nbsp;ArrayList&lt;ITypeFilter&gt;();
		pathURLfilters&nbsp;=&nbsp;new&nbsp;ArrayList&lt;IPathURLFilter&gt;();		this.pathUrls&nbsp;=&nbsp;ClasspathHelper.getUrlsForCurrentClasspath();
	}	public&nbsp;Reflections(final&nbsp;Collection&lt;URL&gt;&nbsp;pathUrls)&nbsp;{		this.pathUrls&nbsp;=&nbsp;pathUrls;
		typeFilters&nbsp;=&nbsp;new&nbsp;ArrayList&lt;ITypeFilter&gt;();
		pathURLfilters&nbsp;=&nbsp;new&nbsp;ArrayList&lt;IPathURLFilter&gt;();
	}	/**
	&nbsp;*&nbsp;@param&nbsp;subTypeFilter
	&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;subTypeFilter&nbsp;to&nbsp;set
	&nbsp;*/
	public&nbsp;void&nbsp;setSubTypeFilter(final&nbsp;ISubTypeFilter&nbsp;subTypeFilter)&nbsp;{		this.subTypeFilter&nbsp;=&nbsp;subTypeFilter;
	}	/**
	&nbsp;*&nbsp;@return&nbsp;the&nbsp;subTypeFilter
	&nbsp;*/
	public&nbsp;ISubTypeFilter&nbsp;getSubTypeFilter()&nbsp;{		return&nbsp;subTypeFilter;
	}	public&nbsp;Reflections&nbsp;addPathURLFilter(final&nbsp;IPathURLFilter&nbsp;pathURLFilter)&nbsp;{		if&nbsp;(null&nbsp;==&nbsp;pathURLFilter)			return&nbsp;this;		if&nbsp;(!this.pathURLfilters.contains(pathURLFilter))			this.pathURLfilters.add(pathURLFilter);		return&nbsp;this;
	}	public&nbsp;Reflections&nbsp;addTypeFilter(final&nbsp;ITypeFilter&nbsp;typeFilter)&nbsp;{		if&nbsp;(null&nbsp;==&nbsp;typeFilter)			return&nbsp;this;		if&nbsp;(!this.typeFilters.contains(typeFilter))			this.typeFilters.add(typeFilter);		return&nbsp;this;
	}	private&nbsp;static&nbsp;final&nbsp;String&nbsp;histFile&nbsp;=&nbsp;"./configuration.REF";	private&nbsp;Document&nbsp;histDom;	public&nbsp;Collection&lt;String&gt;&nbsp;getSubTypesFast(final&nbsp;Class&lt;?&gt;&nbsp;baseType)&nbsp;{//,&nbsp;final&nbsp;String...&nbsp;typeNames
		//首先过滤出当前允许扫描的路径
		final&nbsp;StringBuilder&nbsp;bufPathsId&nbsp;=&nbsp;new&nbsp;StringBuilder(32);		final&nbsp;Map&lt;File,&nbsp;URL&gt;&nbsp;fileUrls&nbsp;=&nbsp;new&nbsp;LinkedHashMap&lt;File,&nbsp;URL&gt;(8);		for&nbsp;(final&nbsp;URL&nbsp;pathUrl&nbsp;:&nbsp;pathUrls)&nbsp;{			if&nbsp;(!acceptPathUrl(pathUrl))				continue;			File&nbsp;file&nbsp;=&nbsp;null;			try&nbsp;{				file&nbsp;=&nbsp;new&nbsp;File(URLDecoder.decode(pathUrl.getFile(),&nbsp;"UTF-8"));
			}&nbsp;catch&nbsp;(final&nbsp;Exception&nbsp;e)&nbsp;{				file&nbsp;=&nbsp;new&nbsp;File(pathUrl.getFile());
			}
			fileUrls.put(file,&nbsp;pathUrl);			if&nbsp;(!file.exists())//is&nbsp;url&nbsp;file?ignore
				continue;
			bufPathsId.append(file.getName()).append(file.lastModified());
		}		final&nbsp;String&nbsp;domId&nbsp;=&nbsp;MD5.getHashString(bufPathsId.toString());		if&nbsp;(null&nbsp;==&nbsp;histDom)
			histDom&nbsp;=&nbsp;W3cUtils.readXml(histFile);		if&nbsp;(null&nbsp;==&nbsp;histDom)
			histDom&nbsp;=&nbsp;W3cUtils.newDom("R");
		Element&nbsp;rootEle&nbsp;=&nbsp;histDom.getDocumentElement();		if&nbsp;(null&nbsp;==&nbsp;rootEle)
			histDom.appendChild(rootEle&nbsp;=&nbsp;histDom.createElement("R"));		if&nbsp;(!domId.equals(rootEle.getAttribute("id")))&nbsp;{
			rootEle.getParentNode().removeChild(rootEle);
			histDom.appendChild(rootEle&nbsp;=&nbsp;histDom.createElement("R"));
			rootEle.setAttribute("id",&nbsp;domId);
		}		final&nbsp;String&nbsp;baseTypeId&nbsp;=&nbsp;MD5.getHashString(baseType.getName());
		Element&nbsp;refEle&nbsp;=&nbsp;W3cUtils.firstChildElement(rootEle,&nbsp;"E",&nbsp;"id",&nbsp;baseTypeId);		if&nbsp;(null&nbsp;!=&nbsp;refEle)&nbsp;{			final&nbsp;List&lt;Element&gt;&nbsp;valueEles&nbsp;=&nbsp;W3cUtils.childElementList(refEle,&nbsp;"F");			final&nbsp;Collection&lt;String&gt;&nbsp;result&nbsp;=&nbsp;new&nbsp;ArrayList&lt;String&gt;(valueEles.size());			for&nbsp;(final&nbsp;Element&nbsp;valueEle&nbsp;:&nbsp;valueEles)&nbsp;{
				result.add(new&nbsp;String(Base64.decodeFast(valueEle.getAttribute("id"))));
			}			return&nbsp;result;
		}		final&nbsp;ThreadPool&lt;ListSubTypes&gt;&nbsp;pool&nbsp;=&nbsp;new&nbsp;ThreadPool&lt;ListSubTypes&gt;();		for&nbsp;(final&nbsp;File&nbsp;fileKey&nbsp;:&nbsp;fileUrls.keySet())&nbsp;{
			pool.execute(new&nbsp;ListSubTypes(baseType,&nbsp;fileKey,&nbsp;fileUrls.get(fileKey)));
		}		try&nbsp;{
			pool.shutdown(3,&nbsp;TimeUnit.MINUTES);
		}&nbsp;catch&nbsp;(final&nbsp;InterruptedException&nbsp;e)&nbsp;{
			e.printStackTrace();//for&nbsp;debug
		}		final&nbsp;Collection&lt;String&gt;&nbsp;result&nbsp;=&nbsp;new&nbsp;ArrayList&lt;String&gt;();		for&nbsp;(final&nbsp;ListSubTypes&nbsp;task&nbsp;:&nbsp;pool.getThreadRunables())&nbsp;{
			result.addAll(task.result);
		}
		refEle&nbsp;=&nbsp;W3cUtils.addEle(rootEle,&nbsp;"E");
		refEle.setAttribute("id",&nbsp;baseTypeId);		for&nbsp;(final&nbsp;String&nbsp;itm&nbsp;:&nbsp;result)&nbsp;{
			W3cUtils.addEle(refEle,&nbsp;"F").setAttribute("id",&nbsp;Base64.encodeToString(itm.getBytes(),&nbsp;false));
		}		try&nbsp;{
			W3cUtils.writeXmlDocument(histFile,&nbsp;histDom);
		}&nbsp;catch&nbsp;(final&nbsp;Exception&nbsp;e)&nbsp;{
		}		return&nbsp;result;
	}	/**
	&nbsp;*&nbsp;@see&nbsp;{@link&nbsp;ReflectUtils#createSharedReflections(String...)}
	&nbsp;*&nbsp;@see&nbsp;{@link&nbsp;ReflectUtils#setSharedReflections(Reflections)}
	&nbsp;*&nbsp;@see&nbsp;{@link&nbsp;ReflectUtils#listSubClass(Class)}
	&nbsp;*&nbsp;@param&nbsp;baseType
	&nbsp;*&nbsp;@return
	&nbsp;*/
	public&nbsp;Collection&lt;String&gt;&nbsp;getSubTypes(final&nbsp;Class&lt;?&gt;&nbsp;baseType,&nbsp;final&nbsp;String...&nbsp;typeNames)&nbsp;{//
		final&nbsp;ThreadPool&lt;ListSubTypes&gt;&nbsp;pool&nbsp;=&nbsp;new&nbsp;ThreadPool&lt;ListSubTypes&gt;();		for&nbsp;(final&nbsp;URL&nbsp;pathUrl&nbsp;:&nbsp;pathUrls)&nbsp;{			if&nbsp;(!acceptPathUrl(pathUrl))				continue;			File&nbsp;file&nbsp;=&nbsp;null;			try&nbsp;{				file&nbsp;=&nbsp;new&nbsp;File(URLDecoder.decode(pathUrl.getFile(),&nbsp;"UTF-8"));
			}&nbsp;catch&nbsp;(final&nbsp;Exception&nbsp;e)&nbsp;{				file&nbsp;=&nbsp;new&nbsp;File(pathUrl.getFile());
			}
			pool.execute(new&nbsp;ListSubTypes(baseType,&nbsp;file,&nbsp;pathUrl,&nbsp;typeNames));
		}		try&nbsp;{
			pool.shutdown(3,&nbsp;TimeUnit.MINUTES);
		}&nbsp;catch&nbsp;(final&nbsp;InterruptedException&nbsp;e)&nbsp;{
			e.printStackTrace();//for&nbsp;debug
		}		final&nbsp;Collection&lt;String&gt;&nbsp;result&nbsp;=&nbsp;new&nbsp;ArrayList&lt;String&gt;();		for&nbsp;(final&nbsp;ListSubTypes&nbsp;task&nbsp;:&nbsp;pool.getThreadRunables())&nbsp;{
			result.addAll(task.result);
		}		return&nbsp;result;
	}	class&nbsp;ListSubTypes&nbsp;implements&nbsp;Runnable&nbsp;{		final&nbsp;File&nbsp;file;		final&nbsp;Class&lt;?&gt;&nbsp;baseType;		final&nbsp;URL&nbsp;pathUrl;		final&nbsp;String[]&nbsp;typeNames;		public&nbsp;ListSubTypes(final&nbsp;Class&lt;?&gt;&nbsp;baseType,&nbsp;final&nbsp;File&nbsp;file,&nbsp;final&nbsp;URL&nbsp;pathUrl,&nbsp;final&nbsp;String...&nbsp;typeNames)&nbsp;{			this.baseType&nbsp;=&nbsp;baseType;			this.file&nbsp;=&nbsp;file;			this.pathUrl&nbsp;=&nbsp;pathUrl;			this.typeNames&nbsp;=&nbsp;typeNames;
		}

		Collection&lt;String&gt;&nbsp;result&nbsp;=&nbsp;new&nbsp;ArrayList&lt;String&gt;(4);		@Override
		public&nbsp;void&nbsp;run()&nbsp;{			if&nbsp;(file.isDirectory())&nbsp;{
				listSubTypesFromDirectory(file,&nbsp;baseType,&nbsp;pathUrl,&nbsp;file,&nbsp;result,&nbsp;typeNames);
			}&nbsp;else
				listSubTypesFromJar(baseType,&nbsp;pathUrl,&nbsp;result,&nbsp;typeNames);
		}
	}	/**
	&nbsp;*&nbsp;@param&nbsp;baseType
	&nbsp;*&nbsp;@param&nbsp;pathUrl
	&nbsp;*&nbsp;@param&nbsp;result
	&nbsp;*/
	public&nbsp;void&nbsp;listSubTypesFromDirectory(final&nbsp;File&nbsp;baseDirectory,&nbsp;final&nbsp;Class&lt;?&gt;&nbsp;baseType,&nbsp;final&nbsp;URL&nbsp;pathUrl,&nbsp;final&nbsp;File&nbsp;directory,			final&nbsp;Collection&lt;String&gt;&nbsp;result,&nbsp;final&nbsp;String...&nbsp;typeNames)&nbsp;{		File[]&nbsp;files&nbsp;=&nbsp;directory.listFiles();		if&nbsp;(null&nbsp;==&nbsp;files)
			files&nbsp;=&nbsp;new&nbsp;File[]&nbsp;{};
		String&nbsp;clazzPath;		final&nbsp;int&nbsp;baseDirLen&nbsp;=&nbsp;baseDirectory.getAbsolutePath().length()&nbsp;+&nbsp;1;		for&nbsp;(final&nbsp;File&nbsp;file&nbsp;:&nbsp;files)&nbsp;{			if&nbsp;(file.isDirectory())&nbsp;{
				listSubTypesFromDirectory(baseDirectory,&nbsp;baseType,&nbsp;pathUrl,&nbsp;file,&nbsp;result,&nbsp;typeNames);
			}&nbsp;else&nbsp;{
				clazzPath&nbsp;=&nbsp;file.getAbsolutePath().substring(baseDirLen);
				clazzPath&nbsp;=&nbsp;clazzPath.replace('\\',&nbsp;'/');
				doTypesFilter(baseType,&nbsp;pathUrl,&nbsp;result,&nbsp;clazzPath,&nbsp;typeNames);
			}
		}
	}	/**
	&nbsp;*&nbsp;@param&nbsp;baseType
	&nbsp;*&nbsp;@param&nbsp;pathUrl
	&nbsp;*&nbsp;@param&nbsp;result
	&nbsp;*/
	public&nbsp;void&nbsp;listSubTypesFromJar(final&nbsp;Class&lt;?&gt;&nbsp;baseType,&nbsp;URL&nbsp;pathUrl,&nbsp;final&nbsp;Collection&lt;String&gt;&nbsp;result,&nbsp;final&nbsp;String...&nbsp;typeNames)&nbsp;{		try&nbsp;{			//&nbsp;It&nbsp;does&nbsp;not&nbsp;work&nbsp;with&nbsp;the&nbsp;filesystem:&nbsp;we&nbsp;must
			//&nbsp;be&nbsp;in&nbsp;the&nbsp;case&nbsp;of&nbsp;a&nbsp;package&nbsp;contained&nbsp;in&nbsp;a&nbsp;jar&nbsp;file.
			JarFile&nbsp;jarFile&nbsp;=&nbsp;null;			try&nbsp;{				if&nbsp;("file".equals(pathUrl.getProtocol()))
					pathUrl&nbsp;=&nbsp;new&nbsp;URL("jar:"&nbsp;+&nbsp;pathUrl.toExternalForm()&nbsp;+&nbsp;"!/");
				jarFile&nbsp;=&nbsp;((JarURLConnection)&nbsp;pathUrl.openConnection()).getJarFile();
			}&nbsp;catch&nbsp;(final&nbsp;Exception&nbsp;e)&nbsp;{				final&nbsp;String&nbsp;filePath&nbsp;=&nbsp;pathUrl.getFile();				//&nbsp;if&nbsp;on&nbsp;win&nbsp;platform
				if&nbsp;(filePath.indexOf(':')&nbsp;!=&nbsp;-1)&nbsp;{					if&nbsp;(pathUrl.getFile().charAt(0)&nbsp;==&nbsp;'/')
						jarFile&nbsp;=&nbsp;new&nbsp;JarFile(filePath.substring(1));
				}				if&nbsp;(null&nbsp;==&nbsp;jarFile)
					jarFile&nbsp;=&nbsp;new&nbsp;JarFile(filePath);
			}			final&nbsp;Enumeration&lt;JarEntry&gt;&nbsp;e&nbsp;=&nbsp;jarFile.entries();
			ZipEntry&nbsp;entry;			while&nbsp;(e.hasMoreElements())&nbsp;{
				entry&nbsp;=&nbsp;e.nextElement();
				doTypesFilter(baseType,&nbsp;pathUrl,&nbsp;result,&nbsp;entry.getName(),&nbsp;typeNames);
			}
		}&nbsp;catch&nbsp;(final&nbsp;IOException&nbsp;ioex)&nbsp;{
		}
	}	private&nbsp;void&nbsp;doTypesFilter(final&nbsp;Class&lt;?&gt;&nbsp;baseType,&nbsp;final&nbsp;URL&nbsp;pathUrl,&nbsp;final&nbsp;Collection&lt;String&gt;&nbsp;result,&nbsp;final&nbsp;String&nbsp;clazzPath,			final&nbsp;String...&nbsp;typeNames)&nbsp;{		if&nbsp;(!clazzPath.endsWith(".class"))			return;		final&nbsp;int&nbsp;lastDotIdx&nbsp;=&nbsp;clazzPath.lastIndexOf('.');		if&nbsp;(-1&nbsp;==&nbsp;lastDotIdx)			return;		final&nbsp;String&nbsp;typeDef&nbsp;=&nbsp;clazzPath.substring(0,&nbsp;lastDotIdx).replace('/',&nbsp;'.');		if&nbsp;(null&nbsp;!=&nbsp;typeNames&nbsp;&amp;&amp;&nbsp;typeNames.length&nbsp;&gt;&nbsp;0)&nbsp;{			final&nbsp;int&nbsp;lastDot&nbsp;=&nbsp;typeDef.lastIndexOf('.');			if&nbsp;(lastDot&nbsp;==&nbsp;-1)				return;			final&nbsp;String&nbsp;typeName&nbsp;=&nbsp;typeDef.substring(lastDot&nbsp;+&nbsp;1);			boolean&nbsp;withLiked&nbsp;=&nbsp;false;			for&nbsp;(final&nbsp;String&nbsp;tmpTypeName&nbsp;:&nbsp;typeNames)&nbsp;{				if&nbsp;(!typeName.contains(tmpTypeName))					continue;
				withLiked&nbsp;=&nbsp;true;				break;
			}			if&nbsp;(withLiked&nbsp;==&nbsp;false)				return;
		}		if&nbsp;(this.typeFilters.isEmpty())&nbsp;{			if&nbsp;(null&nbsp;==&nbsp;this.subTypeFilter&nbsp;||&nbsp;this.subTypeFilter.accept(baseType,&nbsp;pathUrl,&nbsp;clazzPath))
				result.add(typeDef);
		}&nbsp;else&nbsp;{			for&nbsp;(final&nbsp;ITypeFilter&nbsp;typeFilter&nbsp;:&nbsp;this.typeFilters)&nbsp;{				if&nbsp;(!typeFilter.accept(clazzPath))					continue;				if&nbsp;(null&nbsp;==&nbsp;this.subTypeFilter&nbsp;||&nbsp;this.subTypeFilter.accept(baseType,&nbsp;pathUrl,&nbsp;clazzPath))
					result.add(typeDef);
			}
		}
	}	/**
	&nbsp;*&nbsp;@param&nbsp;pathUrl
	&nbsp;*&nbsp;@return
	&nbsp;*/
	private&nbsp;boolean&nbsp;acceptPathUrl(final&nbsp;URL&nbsp;pathUrl)&nbsp;{		if&nbsp;(this.pathURLfilters.isEmpty())			return&nbsp;true;		for&nbsp;(final&nbsp;IPathURLFilter&nbsp;pathURLFilter&nbsp;:&nbsp;this.pathURLfilters)&nbsp;{			if&nbsp;(pathURLFilter.accept(pathUrl))				return&nbsp;true;
		}		return&nbsp;false;
	}
}</pre>
    <pre class="hljs gradle" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">package&nbsp;net.simple.reflect;import&nbsp;java.beans.Beans;import&nbsp;java.io.File;import&nbsp;java.io.IOException;import&nbsp;java.io.UnsupportedEncodingException;import&nbsp;java.net.JarURLConnection;import&nbsp;java.net.URL;import&nbsp;java.net.URLDecoder;import&nbsp;java.util.ArrayList;import&nbsp;java.util.Collection;import&nbsp;java.util.Collections;import&nbsp;java.util.Enumeration;import&nbsp;java.util.List;import&nbsp;java.util.jar.JarEntry;import&nbsp;java.util.jar.JarFile;import&nbsp;java.util.zip.ZipEntry;import&nbsp;net.simple.reflect.filter.PathURLFilter;import&nbsp;net.simple.reflect.filter.SampleSubInstanceFilter;import&nbsp;net.simple.reflect.filter.TypeFilter;/**
&nbsp;*&nbsp;
&nbsp;*&nbsp;@author&nbsp;李岩飞
&nbsp;*&nbsp;@email&nbsp;eliyanfei@126.com	
&nbsp;*&nbsp;2016年11月2日&nbsp;下午3:24:02
&nbsp;*
&nbsp;*/public&nbsp;final&nbsp;class&nbsp;ReflectUtils&nbsp;{	public&nbsp;static&nbsp;final&nbsp;String&nbsp;VAR_START_FLAG&nbsp;=&nbsp;"${";	public&nbsp;static&nbsp;final&nbsp;String&nbsp;VAR_END_FLAG&nbsp;=&nbsp;"}";	private&nbsp;static&nbsp;Reflections&nbsp;sharedReflections;	static&nbsp;final&nbsp;Collection&lt;String&gt;&nbsp;EMP_COLL&nbsp;=&nbsp;Collections.emptyList();	public&nbsp;static&nbsp;final&nbsp;void&nbsp;createSharedReflections(final&nbsp;String...&nbsp;filterExts)&nbsp;{		final&nbsp;Reflections&nbsp;refs&nbsp;=&nbsp;new&nbsp;Reflections();
		refs.addPathURLFilter(new&nbsp;PathURLFilter(filterExts));//
		refs.addTypeFilter(TypeFilter.DEFAULT);
		refs.setSubTypeFilter(SampleSubInstanceFilter.DEFAULT);
		ReflectUtils.setSharedReflections(refs);
	}	/**
	&nbsp;*&nbsp;此方法用于绑定一个通用的共享类型遍列工具.
	&nbsp;*&nbsp;@param&nbsp;sharedReflections
	&nbsp;*/
	public&nbsp;static&nbsp;final&nbsp;void&nbsp;setSharedReflections(final&nbsp;Reflections&nbsp;sharedReflections)&nbsp;{
		ReflectUtils.sharedReflections&nbsp;=&nbsp;sharedReflections;
	}	/**
	&nbsp;*&nbsp;调用此方法之前必须先设置共享的类型遍列工具,参考:{@link&nbsp;#setSharedReflections(Reflections)},
	&nbsp;*&nbsp;此方法主要使更方便的遍列给定类的实现,
	&nbsp;*/
	public&nbsp;static&nbsp;final&nbsp;Collection&lt;String&gt;&nbsp;listSubClass(final&nbsp;Class&lt;?&gt;&nbsp;baseType,&nbsp;final&nbsp;String...&nbsp;typeNames)&nbsp;{//
		if&nbsp;(null&nbsp;==&nbsp;sharedReflections)			return&nbsp;EMP_COLL;		//调用阶段由于可能增加新的子类实现,需要每次都重新扫描,只有在发布的产品时使用保存记录的方法以提高启动速度.
		return&nbsp;Beans.isDesignTime()&nbsp;?&nbsp;sharedReflections.getSubTypes(baseType,&nbsp;typeNames)&nbsp;:&nbsp;sharedReflections.getSubTypesFast(baseType);
	}	public&nbsp;static&nbsp;List&lt;Class&lt;?&gt;&gt;&nbsp;listClassOfPackage(final&nbsp;Class&lt;?&gt;&nbsp;cType,&nbsp;final&nbsp;String&nbsp;extenion)&nbsp;{		final&nbsp;List&lt;Class&lt;?&gt;&gt;&nbsp;result&nbsp;=&nbsp;new&nbsp;ArrayList&lt;Class&lt;?&gt;&gt;();		final&nbsp;List&lt;String&gt;&nbsp;cPath&nbsp;=&nbsp;ReflectUtils.listClassCanonicalNameOfPackage(cType,&nbsp;extenion);		for&nbsp;(final&nbsp;String&nbsp;path&nbsp;:&nbsp;cPath)&nbsp;{			try&nbsp;{
				result.add(Class.forName(path,&nbsp;false,&nbsp;Thread.currentThread().getContextClassLoader()));
			}&nbsp;catch&nbsp;(final&nbsp;Exception&nbsp;e)&nbsp;{				//&nbsp;ignore
			}
		}		return&nbsp;result;
	}	public&nbsp;static&nbsp;List&lt;String&gt;&nbsp;listClassCanonicalNameOfPackage(final&nbsp;Class&lt;?&gt;&nbsp;clazz,&nbsp;final&nbsp;String&nbsp;extenion)&nbsp;{		return&nbsp;ReflectUtils.listNameOfPackage(clazz,&nbsp;extenion,&nbsp;true);
	}	public&nbsp;static&nbsp;List&lt;String&gt;&nbsp;listClassNameOfPackage(final&nbsp;Class&lt;?&gt;&nbsp;clazz,&nbsp;final&nbsp;String&nbsp;extenion)&nbsp;{		return&nbsp;ReflectUtils.listNameOfPackage(clazz,&nbsp;extenion,&nbsp;false);
	}	public&nbsp;static&nbsp;List&lt;String&gt;&nbsp;listNameOfPackage(final&nbsp;Class&lt;?&gt;&nbsp;clazz,&nbsp;final&nbsp;String&nbsp;extenion,&nbsp;final&nbsp;boolean&nbsp;fullPkgName)&nbsp;{		return&nbsp;ReflectUtils.listNameOfPackage(clazz.getName().replace('.',&nbsp;'/')&nbsp;+&nbsp;".class",&nbsp;extenion,&nbsp;fullPkgName);
	}	public&nbsp;static&nbsp;List&lt;String&gt;&nbsp;listNameOfPackage(final&nbsp;String&nbsp;clazzPkg,&nbsp;final&nbsp;String&nbsp;extenion,&nbsp;final&nbsp;boolean&nbsp;fullPkgName)&nbsp;{		final&nbsp;List&lt;String&gt;&nbsp;result&nbsp;=&nbsp;new&nbsp;ArrayList&lt;String&gt;();		final&nbsp;StringBuffer&nbsp;pkgBuf&nbsp;=&nbsp;new&nbsp;StringBuffer(clazzPkg);		if&nbsp;(pkgBuf.charAt(0)&nbsp;!=&nbsp;'/')
			pkgBuf.insert(0,&nbsp;'/');		final&nbsp;URL&nbsp;urlPath&nbsp;=&nbsp;ReflectUtils.class.getResource(pkgBuf.toString());		if&nbsp;(null&nbsp;==&nbsp;urlPath)			return&nbsp;result;

		String&nbsp;checkedExtenion&nbsp;=&nbsp;extenion;		if&nbsp;(!extenion.endsWith(".class"))
			checkedExtenion&nbsp;=&nbsp;extenion&nbsp;+&nbsp;".class";		if&nbsp;(pkgBuf.toString().endsWith(".class"))
			pkgBuf.delete(pkgBuf.lastIndexOf("/"),&nbsp;pkgBuf.length());

		pkgBuf.deleteCharAt(0);		final&nbsp;StringBuffer&nbsp;fileUrl&nbsp;=&nbsp;new&nbsp;StringBuffer();		try&nbsp;{
			fileUrl.append(URLDecoder.decode(urlPath.toExternalForm(),&nbsp;"UTF-8"));
		}&nbsp;catch&nbsp;(final&nbsp;UnsupportedEncodingException&nbsp;e1)&nbsp;{
			fileUrl.append(urlPath.toExternalForm());
		}		if&nbsp;(fileUrl.toString().startsWith("file:"))&nbsp;{
			fileUrl.delete(0,&nbsp;5);//&nbsp;delete&nbsp;file:&nbsp;flag
			if&nbsp;(fileUrl.indexOf(":")&nbsp;!=&nbsp;-1)
				fileUrl.deleteCharAt(0);//&nbsp;delete&nbsp;flag
			final&nbsp;String&nbsp;baseDir&nbsp;=&nbsp;fileUrl.substring(0,&nbsp;fileUrl.lastIndexOf("classes")&nbsp;+&nbsp;8);
			ReflectUtils.doListNameOfPackageInDirectory(new&nbsp;File(baseDir),&nbsp;new&nbsp;File(baseDir),&nbsp;result,&nbsp;pkgBuf.toString(),&nbsp;checkedExtenion,&nbsp;fullPkgName);
		}&nbsp;else&nbsp;{
			ReflectUtils.doListNameOfPackageInJar(urlPath,&nbsp;urlPath,&nbsp;result,&nbsp;pkgBuf.toString(),&nbsp;checkedExtenion,&nbsp;fullPkgName);
		}		return&nbsp;result;
	}	/**
	&nbsp;*/
	private&nbsp;static&nbsp;void&nbsp;doListNameOfPackageInJar(final&nbsp;URL&nbsp;baseUrl,&nbsp;final&nbsp;URL&nbsp;urlPath,&nbsp;final&nbsp;List&lt;String&gt;&nbsp;result,&nbsp;final&nbsp;String&nbsp;clazzPkg,&nbsp;final&nbsp;String&nbsp;extenion,&nbsp;final&nbsp;boolean&nbsp;fullPkgName)&nbsp;{		try&nbsp;{			//&nbsp;It&nbsp;does&nbsp;not&nbsp;work&nbsp;with&nbsp;the&nbsp;filesystem:&nbsp;we&nbsp;must
			//&nbsp;be&nbsp;in&nbsp;the&nbsp;case&nbsp;of&nbsp;a&nbsp;package&nbsp;contained&nbsp;in&nbsp;a&nbsp;jar&nbsp;file.
			final&nbsp;JarURLConnection&nbsp;conn&nbsp;=&nbsp;(JarURLConnection)&nbsp;urlPath.openConnection();			final&nbsp;JarFile&nbsp;jfile&nbsp;=&nbsp;conn.getJarFile();			final&nbsp;Enumeration&lt;JarEntry&gt;&nbsp;e&nbsp;=&nbsp;jfile.entries();

			ZipEntry&nbsp;entry;
			String&nbsp;entryname;			while&nbsp;(e.hasMoreElements())&nbsp;{
				entry&nbsp;=&nbsp;e.nextElement();
				entryname&nbsp;=&nbsp;entry.getName();				if&nbsp;(entryname.startsWith(clazzPkg)&nbsp;&amp;&amp;&nbsp;entryname.endsWith(extenion))&nbsp;{					if&nbsp;(fullPkgName)
						result.add(entryname.substring(0,&nbsp;entryname.lastIndexOf('.')).replace('/',&nbsp;'.'));					else
						result.add(entryname.substring(entryname.lastIndexOf('/')&nbsp;+&nbsp;1,&nbsp;entryname.lastIndexOf('.')));
				}
			}
		}&nbsp;catch&nbsp;(final&nbsp;IOException&nbsp;ioex)&nbsp;{
		}
	}	private&nbsp;static&nbsp;void&nbsp;doListNameOfPackageInDirectory(final&nbsp;File&nbsp;baseDirectory,&nbsp;final&nbsp;File&nbsp;directory,&nbsp;final&nbsp;List&lt;String&gt;&nbsp;result,&nbsp;final&nbsp;String&nbsp;clazzPkg,&nbsp;final&nbsp;String&nbsp;extenion,			final&nbsp;boolean&nbsp;fullPkgName)&nbsp;{		File[]&nbsp;files&nbsp;=&nbsp;directory.listFiles();		if&nbsp;(null&nbsp;==&nbsp;files)
			files&nbsp;=&nbsp;new&nbsp;File[]&nbsp;{};
		String&nbsp;clazzPath;		final&nbsp;int&nbsp;baseDirLen&nbsp;=&nbsp;baseDirectory.getAbsolutePath().length()&nbsp;+&nbsp;1;		for&nbsp;(final&nbsp;File&nbsp;file&nbsp;:&nbsp;files)&nbsp;{			if&nbsp;(file.isDirectory())&nbsp;{
				ReflectUtils.doListNameOfPackageInDirectory(baseDirectory,&nbsp;file,&nbsp;result,&nbsp;clazzPkg,&nbsp;extenion,&nbsp;fullPkgName);
			}&nbsp;else&nbsp;{				if&nbsp;(!file.getName().endsWith(extenion))					continue;				if&nbsp;(fullPkgName)&nbsp;{
					clazzPath&nbsp;=&nbsp;file.getAbsolutePath().substring(baseDirLen);
					clazzPath&nbsp;=&nbsp;clazzPath.substring(0,&nbsp;clazzPath.length()&nbsp;-&nbsp;6);
					result.add(clazzPath.replace(File.separatorChar,&nbsp;'.'));
				}&nbsp;else&nbsp;{
					result.add(file.getName().substring(0,&nbsp;file.getName().length()&nbsp;-&nbsp;6));
				}
			}
		}
	}	public&nbsp;static&nbsp;final&nbsp;&lt;T&gt;&nbsp;T&nbsp;initClass(final&nbsp;String&nbsp;implClass,&nbsp;final&nbsp;Class&lt;T&gt;&nbsp;tType)&nbsp;{		return&nbsp;ReflectUtils.initClass(implClass,&nbsp;tType,&nbsp;true);
	}	public&nbsp;static&nbsp;final&nbsp;&lt;T&gt;&nbsp;T&nbsp;initClass(final&nbsp;String&nbsp;implClass,&nbsp;final&nbsp;Class&lt;T&gt;&nbsp;tType,&nbsp;final&nbsp;boolean&nbsp;doInit)&nbsp;{		try&nbsp;{			final&nbsp;Object&nbsp;object&nbsp;=&nbsp;Class.forName(implClass,&nbsp;doInit,&nbsp;Thread.currentThread().getContextClassLoader()).newInstance();			return&nbsp;tType.cast(object);
		}&nbsp;catch&nbsp;(final&nbsp;Throwable&nbsp;e)&nbsp;{			return&nbsp;null;
		}
	}
}</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px;">&nbsp;</p>
    <p><br></p>
   </div> 
  </div>  
 </body>
</html>